/*-------------------------------------------------------------------------*\
**  STON - Strongly Typed Object Notation                                  **
**  Copyright (c) 2009, Erkki Lindpere. All rights reserved.               **
**  http://code.google.com/p/ston/                                         **
**                                                                         **
**  This software is released under the terms of the Revised BSD License.  **
**  There is NO WARRANTY. See the file LICENSE for the full text.          **
\*-------------------------------------------------------------------------*/
package org.villane.ston

/**
 * Extends STON Parser with primitives (except char) and other common types.
 * 
 * Types defined:
 * Byte, Short, Int, Long, BigInt
 * Float, Double, BigDecimal
 * Boolean
 * String
 */
trait StandardTypes { self: STONParser =>
  self match {
    case me: ReflectiveTypes => 
      me.registerType(classOf[Byte], me.ByteType)
      me.registerType(classOf[Short], me.ShortType)
      me.registerType(classOf[Int], me.IntType)
      me.registerType(classOf[Long], me.LongType)
      me.registerType(classOf[BigInt], me.BigIntType)
      me.registerType(classOf[Float], me.FloatType)
      me.registerType(classOf[Double], me.DoubleType)
      me.registerType(classOf[BigDecimal], me.BigDecimalType)
      me.registerType(classOf[Boolean], me.BooleanType)
      me.registerType(classOf[String], me.StringType)
    case _ =>
  }

  def byteProperty(name: String) = singleProperty(name, ByteType)
  def shortProperty(name: String) = singleProperty(name, ShortType)
  def intProperty(name: String) = singleProperty(name, IntType)
  def longProperty(name: String) = singleProperty(name, LongType)
  def bigIntProperty(name: String) = singleProperty(name, BigIntType)
  def floatProperty(name: String) = singleProperty(name, FloatType)
  def doubleProperty(name: String) = singleProperty(name, DoubleType)
  def bigDecimalProperty(name: String) = singleProperty(name, BigDecimalType)
  def booleanProperty(name: String) = singleProperty(name, BooleanType)
  def stringProperty(name: String) = singleProperty(name, StringType)

  case object ByteType extends SimpleType(classOf[Byte]) {
    val defaultValue: Byte = 0
    def parser = namedValue(numericLit ^^ { _.toByte })
  }

  case object ShortType extends SimpleType(classOf[Short]) {
    val defaultValue: Short = 0
    def parser = namedValue(numericLit ^^ { _.toShort })
  }

  case object IntType extends SimpleType(classOf[Int]) {
    val defaultValue = 0
    def parser = namedValue(numericLit ^^ { _.toInt })
  }

  case object LongType extends SimpleType(classOf[Long]) {
    val defaultValue = 0L
    def parser = namedValue(numericLit ^^ { _.toLong })
  }

  case object BigIntType extends SimpleType(classOf[BigInt]) {
    val defaultValue = BigInt(0)
    def parser = namedValue(numericLit ^^ { BigInt(_) } )
  }

  case object FloatType extends SimpleType(classOf[Float]) {
    val defaultValue = 0f
    def parser = namedValue(numericLit ^^ { _.toFloat })
  }

  case object DoubleType extends SimpleType(classOf[Double]) {
    val defaultValue = 0d
    def parser = namedValue(numericLit ^^ { _.toDouble })
  }

  case object BigDecimalType extends SimpleType(classOf[BigDecimal]) {
    val defaultValue = BigDecimal(0)
    def parser = namedValue(numericLit ^^ { BigDecimal(_) } )
  }

  case object BooleanType extends SimpleType(classOf[Boolean]) {
    val defaultValue = false
    def parser = namedValue(("true" | "false") ^^ { case v => v.toBoolean })
  }

  case object StringType extends SimpleType(classOf[String]) {
    val defaultValue = null
    def parser = namedValue(stringLit)
  }
}
